﻿using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using Orleans.Runtime;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Client
{
    public class OrleansClientHelper
    {
        private OrleansClientBuilderContext BuilderContext { get; set; }

        public OrleansClientHelper(OrleansClientBuilderContext context) {
            this.BuilderContext = context;
        }

        /// <summary>
        /// Builder
        /// </summary>
        /// <returns></returns>
        private IClusterClient ClusterClientBuild()
        {
            var builder = new ClientBuilder();

            builder.Configure<ClusterOptions>(options =>
            {
                options.ClusterId = this.BuilderContext.ClusterId;
                options.ServiceId = this.BuilderContext.ServiceId;
            });

            builder.UseZooKeeperClustering(option =>
            {
                option.ConnectionString = this.BuilderContext.ZookeeperConnectionString;
            });

            IClusterClient iClusterClient = builder.Build();

            return iClusterClient;


        }

        /// <summary>
        /// 启动连接服务
        /// </summary>
        /// <returns></returns>
        public async Task<IClusterClient> StartConnectAsync()
        {
            var iClusterClient = this.ClusterClientBuild();

            int attempt = 0;
            int InitializeAttemptsBeforeFailing = 5;

            await iClusterClient.Connect(async exception =>
            {
                if (exception.GetType() != typeof(SiloUnavailableException))
                {
                    Console.WriteLine($"Cluster client failed to connect to cluster with unexpected error.  Exception: {exception}");
                    return false;
                }
                attempt++;
                Console.WriteLine($"Cluster client attempt {attempt} of {InitializeAttemptsBeforeFailing} failed to connect to cluster.  Exception: {exception}");
                if (attempt > InitializeAttemptsBeforeFailing)
                {
                    return false;
                }
                await Task.Delay(TimeSpan.FromSeconds(3));
                return true;

            });

            return iClusterClient;
        }

    }
}
